package com.woody.aggregate.app.web.msgsendrule;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woody.aggregate.ApiLockKeyConst;
import com.woody.aggregate.app.exception.InvalidApiParameterException;
import com.woody.aggregate.application.service.msgsendrule.IMsgSendRuleService;
import com.woody.aggregate.application.service.msgsendrule.IMsgSendRuleTargetRefService;
import com.woody.aggregate.application.service.msgsendrule.converter.MsgSendRuleConverter;
import com.woody.aggregate.infrastructure.msgsendrule.dto.MsgSendRuleInfoDTO;
import com.woody.aggregate.infrastructure.msgsendrule.dto.SaveMsgSendRuleDTO;
import com.woody.aggregate.msgsendrule.api.MsgSendRuleApi;
import com.woody.aggregate.msgsendrule.enums.MsgSendStartTypeEnum;
import com.woody.aggregate.msgsendrule.enums.MsgSendUserScopeEnum;
import com.woody.aggregate.msgsendrule.req.*;
import com.woody.aggregate.msgsendrule.vo.MsgSendRuleInfoVo;
import com.woody.aggregate.msgsendrule.vo.MsgSendRuleVo;
import com.woody.aggregate.msgsendrule.vo.RuleTargetInfoVo;
import com.woody.aggregate.msgsendrule.vo.SaveMsgSendRuleVo;
import com.woody.base.exception.BaseException;
import com.woody.base.model.Response;
import com.woody.common.redis.lock.TryLock;
import io.swagger.annotations.Api;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * &copy; All rights Reserved
 *
 * @author wénkǎi.zhāng 2025-03-19
 */
@RestController
@RequestMapping("messagebox/sendRule")
@Api(tags = "弹窗规则管理")
public class MsgSendRuleController implements MsgSendRuleApi {
    @Autowired
    private IMsgSendRuleService msgSendRuleService;

    @Autowired
    private IMsgSendRuleTargetRefService msgSendRuleTargetRefService;


    @Override
    public Response<Page<MsgSendRuleVo>> listRule(ListMsgSendRuleReq request) {
        Page<MsgSendRuleVo> vo = msgSendRuleService.pageListRule(request);
        return Response.success(vo);
    }

    @Override
    public Response<MsgSendRuleInfoVo> queryRuleDetailById(Integer ruleId) {
        // 查询规则信息
        MsgSendRuleInfoDTO dto = msgSendRuleService.queryRuleDetailById(ruleId);

        if (dto == null) {
            throw new BaseException("弹窗规则不存在");
        }
        // 转换vo
        MsgSendRuleInfoVo vo = MsgSendRuleConverter.convertToInfoVo(dto);
        return Response.success(vo);
    }

    @Override
    @TryLock(keyNameSpace = ApiLockKeyConst.SYS_CATEGORY_CONFIG_KEY, keys = "#request.categoryId")
    public Response<SaveMsgSendRuleVo> saveRule(SaveMsgSendRuleReq request) {
        // 参数校验，如果是定时推送，推送时间不能为空
        if (MsgSendStartTypeEnum.TIMING.getType().equals(request.getStartType()) && request.getStartTime() == null) {
            throw new InvalidApiParameterException("定时推送时间不能为空");
        }

        SaveMsgSendRuleDTO saveDto = MsgSendRuleConverter.convertToSaveDto(request);

        SaveMsgSendRuleVo resVo = new SaveMsgSendRuleVo();
        if (request.getRuleId() != null) {
            // 编辑规则基础信息
            msgSendRuleService.editRule(request.getRuleId(), saveDto);
            resVo.setRuleId(request.getRuleId());
        } else {
            // 创建规则时，如果是精准推送，推送用户不能为空
            if (MsgSendUserScopeEnum.SPECIFY.getScope().equals(request.getUserScope()) && CollectionUtils.isEmpty(request.getUserIds())) {
                throw new InvalidApiParameterException("精准推送门店列表不能为空");
            }
            List<Long> userIds = CollectionUtils.isEmpty(request.getUserIds()) ? Collections.emptyList() : request.getUserIds().stream().distinct().collect(Collectors.toList());
            Integer ruleId = msgSendRuleService.addRule(saveDto, userIds);
            resVo.setRuleId(ruleId);
        }
        return Response.success(resVo);
    }

    @Override
    public Response<Page<RuleTargetInfoVo>> listSelectedTarget(ListSelectedTargetReq request) {
        Page<RuleTargetInfoVo> pageResult = msgSendRuleTargetRefService.queryTargetsByRuleId(request.genPage(), request.getRuleId());
        return Response.success(pageResult);
    }

    @Override
    public Response<List<Long>> queryBoundTargetIds(QueryBoundTargetIdsReq request) {
        List<Long> targets = msgSendRuleTargetRefService.getBoundTargets(request.getRuleId(), request.getTargetType(), request.getBizIds());
        return Response.success(targets);
    }

    @Override
    @TryLock(keyNameSpace = ApiLockKeyConst.MSG_SEND_RULE_TARGET_REF_UPDATE, keys = "#request.ruleId")
    public Response<Void> updateTargetRef(UpdateSelectedUserListReq request) {
        List<Long> addIds = Optional.ofNullable(request.getAddUserIds()).orElse(Collections.emptyList());
        List<Long> removeIds = Optional.ofNullable(request.getRemoveUserIds()).orElse(Collections.emptyList());


        msgSendRuleTargetRefService.updateTargetRef(request.getRuleId(), request.getTargetType(), addIds, removeIds, request.getOperatorUserId());

        return Response.success();
    }

    @Override
    public Response<Void> deleteRule(Integer ruleId) {
        msgSendRuleService.deleteRule(ruleId);
        return Response.success();
    }
}
